package cn.cas.mango.util;

import cn.cas.mango.util.string.StringUtils;
import lombok.extern.slf4j.Slf4j;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
@Slf4j
public class RenderDateUtil {

  public static Pair<String, String> getAYearStartEnd() {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    LocalDate date = LocalDate.now();
    String end = formatter.format(date);
    return new Pair<>(LocalDate.of(date.getYear() - 1,
        date.getMonthValue(), 1).format(formatter), end);
  }


  public static Pair<String, String> getRecent2Days() {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    String end = LocalDate.now().format(formatter);
    LocalDate localDate = LocalDate.now().minusDays(2);
    return new Pair<>(LocalDate.of(localDate.getYear(), localDate.getMonthValue(),
        localDate.getDayOfMonth()).format(formatter), end);
  }

  public static Pair<String, String> getRecent1Month() {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    String end = LocalDate.now().format(formatter);
    LocalDate localDate = LocalDate.now().minusDays(30);
    return new Pair<>(LocalDate.of(localDate.getYear(), localDate.getMonthValue(),
        localDate.getDayOfMonth()).format(formatter), end);
  }

  public static Pair<String, String> getRecent1Year() {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    String end = LocalDate.now().format(formatter);
    LocalDate localDate = LocalDate.now().minusDays(365);
    return new Pair<>(LocalDate.of(localDate.getYear(), localDate.getMonthValue(),
        localDate.getDayOfMonth()).format(formatter), end);
  }

  public static Pair<String, String> getRecent3Year() {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    String end = LocalDate.now().format(formatter);
    LocalDate localDate = LocalDate.now().minusDays(365 * 3);
    return new Pair<>(LocalDate.of(localDate.getYear(), localDate.getMonthValue(),
        localDate.getDayOfMonth()).format(formatter), end);
  }


  public static List<String> getLastYearDay() {
    Pair<String, String> startEnd = getAYearStartEnd();
//    return getDistanceDate(startEnd.getKey(), startEnd.getValue());
    return getDistanceDate("2021-05-01", "2022-05-01");
  }

  /**
   * 获取两个日期之间的天.
   */
  public static List<String> getDistanceDate(String startTime, String endTime) {
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
    List<String> dates = new ArrayList<>();
    Date startDateTime = null;
    Date endDateTime = null;
    try {
      startDateTime = simpleDateFormat.parse(startTime);
      endDateTime = simpleDateFormat.parse(endTime);
    } catch (Exception e) {
      e.printStackTrace();
    }
    assert endDateTime != null;
    long differentDays = endDateTime.getTime() - startDateTime.getTime();
    int targetDays = ((int) (differentDays / 86400000L)) + 1;
    Calendar cal = Calendar.getInstance();
    for (int i = 0; i < targetDays; i++) {
      cal.setTime(startDateTime);
      cal.add(Calendar.DATE, i);
      dates.add(simpleDateFormat.format(cal.getTime()));
    }
    return dates;
  }

  /**
   * 获取两个日期之间的月份.
   */
  public static List<String> getDistanceMonth(List<String> dates) {
    List<String> monthList = new ArrayList<>();
    for (String str : dates) {
      String mon = str.substring(0, 7);
      if (!monthList.contains(mon)) {
        monthList.add(mon);
      }
    }
    return monthList;
  }


  /**
   * 获取两个日期之间的月份Map.
   */
  public static LinkedHashMap<String, List<String>> getDistanceMonthMap(List<String> dates) {
    LinkedHashMap<String, List<String>> map = new LinkedHashMap<>();
    for (String str : dates) {
      String mon = str.substring(0, 7);
      if (map.get(mon) != null) {
        map.get(mon).add(str);
      } else {
        List<String> days = new ArrayList<>();
        days.add(str);
        map.put(mon, days);
      }
    }
    return map;
  }

  /**
   * 获取两个日期之间的月份Map.
   */
  public static LinkedHashMap<String, List<String>> getDistanceYearMap(List<String> dates) {
    LinkedHashMap<String, List<String>> map = new LinkedHashMap<>();
    for (String str : dates) {
      String mon = str.substring(0, 4);
      if (map.get(mon) != null) {
        map.get(mon).add(str);
      } else {
        List<String> days = new ArrayList<>();
        days.add(str);
        map.put(mon, days);
      }
    }
    return map;
  }

  /**
   * 获取两个日期之间的年份.
   */
  public static List<String> getDistanceYear(List<String> dates) {
    List<String> monthList = new ArrayList<>();
    for (String str : dates) {
      String mon = str.substring(0, 4);
      if (!monthList.contains(mon)) {
        monthList.add(mon);
      }
    }
    return monthList;
  }

  public static Date transDate(String date) {
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
    try {
      return simpleDateFormat.parse(date);
    } catch (Exception e) {
      log.info("date {} is wrong", date);
      try {
        return simpleDateFormat.parse("2022-02-02");
      } catch (ParseException ex) {
        throw new RuntimeException(ex);
      }
    }
  }

  public static Date transTime(String time) {
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
    try {
      return simpleDateFormat.parse(time);
    } catch (Exception e) {
      log.info("date {} is wrong", time);
      try {
        return simpleDateFormat.parse("2022-02-02 00:00:00");
      } catch (ParseException ex) {
        throw new RuntimeException(ex);
      }
    }
  }



  /**
   *
   * @param date,
   * @return
   */
  public static Pair<String, String> getStartEnd(String date) {
    Pair<String, String> ret;

    if (StringUtils.countChar(date, '-') == 2) {
      ret = new Pair<>(date, date);
    } else if (StringUtils.countChar(date, '-') == 1) {
      DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("yyyy-MM");
      YearMonth yearMonth = YearMonth.parse(date, inputFormatter);

      LocalDate firstDayOfMonth = yearMonth.atDay(1);
      LocalDate lastDayOfMonth = yearMonth.atEndOfMonth();

      DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

      String formattedFirstDay = firstDayOfMonth.format(outputFormatter);
      String formattedLastDay = lastDayOfMonth.format(outputFormatter);
      ret = new Pair<>(formattedFirstDay, formattedLastDay);
    } else {
      DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
      LocalDate startDate = LocalDate.parse(date + "-01-01", formatter);
      String startOfYearStr = startDate.format(formatter);
      // 获取该年的最后一天（12月31日）
      LocalDate endOfYear = startDate.withMonth(12).withDayOfMonth(31);
      String endOfYearStr = endOfYear.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
      ret = new Pair<>(startOfYearStr, endOfYearStr);
    }
    return ret;
  }

  public static String getNow() {
    return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
  }

  public static String getToday() {
    return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
  }

  /**
   * 在原有日期的基础上加一天
   */
  public static String plus1day(String dateString) {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    LocalDate date = LocalDate.parse(dateString, formatter);
    LocalDate nextDay = date.plusDays(1);
    String nextDayString = nextDay.format(formatter);
    return nextDayString;
  }


  /**
   * 在原有日期的基础上加n天
   *
   */
  public static String plusNDay(String dateString, int n) {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    LocalDate date = LocalDate.parse(dateString, formatter);
    LocalDate nextDay = date.plusDays(n);
    String nextDayString = nextDay.format(formatter);
    return nextDayString;
  }
  public static List<String> getMonthsBetween(String startDate, String endDate) {
    List<String> monthsList = new ArrayList<>();

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    LocalDate start = LocalDate.parse(startDate, formatter);
    LocalDate end = LocalDate.parse(endDate, formatter);

    while (!start.isAfter(end)) {
      monthsList.add(start.format(DateTimeFormatter.ofPattern("_yyyyMM")));
      start = start.plusMonths(1);
    }

    return monthsList;
  }
}
